package cn.zaichi.edu.excelcommon.utils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import cn.zaichi.edu.excelcommon.annotations.ExcelField;
import cn.zaichi.edu.excelcommon.entity.DynamicEntity;
import cn.zaichi.edu.excelcommon.entity.ImportTitleEntity;
import cn.zaichi.edu.excelcommon.error.TitleExceptionEnum;
import cn.zaichi.edu.excelcommon.exception.TitleException;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;

/**
 * 表头处理工具类
 */
public class ImportTitleUtil {

    /**
     * 查找上级表头
     * @param row 行下标
     * @param cell 列下标
     * @param titleEntityList 表头集合
     * @param starRow 开始行
     * @param starCell 开始列
     * @return
     */
    private static String getParentCode(int row, int cell, List<ImportTitleEntity> titleEntityList,int starRow,int starCell){
        if(titleEntityList==null||titleEntityList.size()==0){
            return null;
        }
        //一级表头
        if(row<=starRow){
            return null;
        }
        ImportTitleEntity importTitleEntity = titleEntityList.stream().filter(title -> title.getCell() == cell && title.getRow() == row - 1).findFirst().orElse(null);
        if(importTitleEntity==null){
            if(cell==starCell){
                throw new TitleException(TitleExceptionEnum.NOPARENT);
            }
            //递归查找
            return getParentCode(row,cell-1,titleEntityList,starRow,starCell);
        }
        return importTitleEntity.getCode();
    }

    /**
     * 获取上级编码
     * @param entity
     * @param sourceList
     * @param targetList
     * @return
     */
    private static String getParentCode(ImportTitleEntity entity,List<ImportTitleEntity> sourceList,List<ImportTitleEntity> targetList){
        //上级实体
        ImportTitleEntity parent = sourceList.stream().filter(title -> title.getCode().equals(entity.getParentCode())).findFirst().orElse(null);
        if(parent==null){
            return null;
        }
        //当前名称与上级名称相同
        if(entity.getName().equals(parent.getName())){
            return getParentCode(parent,sourceList,targetList);
        }
        //暂存表头集合有上级
        if(targetList.stream().anyMatch(e->e.getCode().equals(parent.getCode()))){
            return parent.getCode();
        }
        //暂存表头集合没有上级
        return getParentCode(parent,sourceList,targetList);

    }

    /**
     * 处理重复行
     * @param titleEntityList
     * @return
     */
    private static List<ImportTitleEntity> repeatRow(List<ImportTitleEntity> titleEntityList,int starRow){

        List<ImportTitleEntity> list=new ArrayList<>();
        for (ImportTitleEntity importTitleEntity : titleEntityList) {
            //起始行
            if(importTitleEntity.getRow()==starRow){
                list.add(importTitleEntity);
                continue;
            }
            //已存在不能重复添加
            if(list.stream().anyMatch(e->e.getCode().equals(importTitleEntity.getCode()))){
                continue;
            }
            //上级实体
            ImportTitleEntity parent = titleEntityList.stream().filter(title -> title.getCode().equals(importTitleEntity.getParentCode())).findFirst().orElse(null);
            if(parent==null){
                continue;
            }
            //当前名称与上级名称相同重复行
            if(importTitleEntity.getName().equals(parent.getName())){
                continue;
            }
            String parentCode = getParentCode(importTitleEntity, titleEntityList, list);
            importTitleEntity.setParentCode(parentCode);
            list.add(importTitleEntity);
        }
        return titleEntityList;
    }

    /**
     * 读取表头,获取动态列
     * @param hssfWorkbook
     * @param clz 映射实体
     * @param endTitleRow 读取表头行下标
     * @return
     */
    public static DynamicEntity getDynamic(Workbook hssfWorkbook, Class<?> clz, int endTitleRow,int starCell) {
        DynamicEntity dynamicEntity=new DynamicEntity();
        //表头只读取第一个sheet
        Sheet hssfSheet = hssfWorkbook.getSheetAt(0);
        Field[] fields = clz.getDeclaredFields();
        for (Field field : fields) {
            ExcelField fieldAnnotation = field.getAnnotation(ExcelField.class);
            if (fieldAnnotation != null) {
                /*动态列*/
                if (fieldAnnotation.dynamic() && StringUtils.isNotBlank(fieldAnnotation.splitFlage())) {
                    if (dynamicEntity.getDynamicColunmns().get(fieldAnnotation.splitFlage()) == null) {
                        dynamicEntity.getDynamicColunmns().put(fieldAnnotation.splitFlage(), new ArrayList<>());
                        dynamicEntity.getDynamicNames().put(fieldAnnotation.splitFlage(), new ArrayList<>());
                    }
                }
            }
        }

        //表头最后一行为真实映射表头
        Row row = hssfSheet.getRow(endTitleRow);
        int lastCellNum = row.getLastCellNum();
        for (int col = starCell; col < lastCellNum; col++) {
            if(row.getCell(col)==null){
                continue;
            }
            String titleName = row.getCell(col).getStringCellValue();
            for (String k : dynamicEntity.getDynamicColunmns().keySet()) {
                if (titleName.contains(k)) {
                    dynamicEntity.getDynamicColunmns().get(k).add(col);
                    dynamicEntity.getDynamicNames().get(k).add(titleName.split(k)[1]);
                }
            }
        }
        return dynamicEntity;
    }


    /**
     * 读取表头
     * @param hssfWorkbook
     * @return
     */
    public static List<ImportTitleEntity> readExcelTitle(Workbook hssfWorkbook, List<CellRangeAddress> combineCell,int startRow, int endRow, int startCell){
        List<ImportTitleEntity> list=new ArrayList<>();
        //表头只读取第一个sheet
        Sheet hssfSheet = hssfWorkbook.getSheetAt(0);
        for (int rowNum = startRow; rowNum <=endRow; rowNum++) {
            Row hssfRow = hssfSheet.getRow(rowNum);
            String value=null;
            if (hssfRow == null) {
                continue;
            }
            int maxCell=hssfRow.getLastCellNum()-1;
            for(int cellNum=startCell;cellNum<=maxCell;cellNum++){
                //获取单元格内容
                String cellValue = ImportCellValue.getCellValue(combineCell, hssfSheet, rowNum, cellNum);
                if(cellValue!=null&&!cellValue.equals(value)){
                    String code=rowNum+"_"+cellNum+"_";
                    ImportTitleEntity entity=new ImportTitleEntity();
                    entity.setCode(code);
                    entity.setName(cellValue);
                    entity.setRow(rowNum);
                    entity.setCell(cellNum);
                    entity.setParentCode(getParentCode(rowNum,cellNum,list,startRow,startCell));
                    list.add(entity);
                    value=cellValue;
                }
            }

        }
        return list;
    }

    /**
     * 获取最后一级
     * @param titleList
     * @return
     */
    public static List<ImportTitleEntity> getLastTitle(List<ImportTitleEntity> titleList){
        List<ImportTitleEntity> list=new ArrayList<>();
        titleList.forEach(title->{
            if(!titleList.stream().anyMatch(e->title.getCode().equals(e.getParentCode()))){
                list.add(title);
            }
        });
        return list;
    }

    /**
     * 获取树形表头
     * @param titleList
     * @return
     */
    public static List<ImportTitleEntity> getTitleTree(List<ImportTitleEntity> titleList){
        List<ImportTitleEntity> list=new ArrayList<>();
        for (ImportTitleEntity title : titleList) {
            if (title.getParentCode()==null) {
                list.add(title);
            }
            for (ImportTitleEntity it : titleList) {
                if (it.getParentCode()!=null
                        &&it.getName()!=null
                        &&it.getParentCode().equals(title.getCode())
                        &&!it.getName().equals(title.getName())) {
                    if (title.getChildrens() == null) {
                        title.setChildrens(new ArrayList<>());
                    }
                    title.getChildrens().add(it);
                }
            }
        }

        int maxRowNum = titleList.stream().mapToInt(e -> Integer.parseInt(e.getCode().split("_")[0])).max().getAsInt();
        //修改表头code
        editCode(list,maxRowNum);
        return list;
    }

    /**
     * 修改表头code
     *  错误数据对应表头为最终表头，此时返回表头的code应该依然为最终表头
     * @param titleList
     * @param maxRowNum
     */
    private static void editCode(List<ImportTitleEntity> titleList,int maxRowNum){
        for (ImportTitleEntity titleEntity : titleList) {
            if(titleEntity.getChildrens()!=null&&titleEntity.getChildrens().size()>0){
                //只修改最终级
                editCode(titleEntity.getChildrens(),maxRowNum);
            }else{
                String[] split = titleEntity.getCode().split("_");
                if(Integer.parseInt(split[0])>=maxRowNum){
                    continue;
                }
                String code=maxRowNum+"_";
                for(int i=1;i<split.length;i++){
                    code+=split[i]+"_";
                }
                titleEntity.setCode(code);
            }

        }
    }




}
